import javax.swing.*;


import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.Iterator;

public class GUI_Game_Board extends JFrame {

	private class ReadyLabel extends JLabel {
		private static final long serialVersionUID = 1L;
		private int ready = 0;
		private int total = 0;
		
		ReadyLabel()
		{
			super();
			setText();
		}
		private void setText()
		{
			super.setText(ready + "/" + total + " players ready        ready");
			invalidate();
		}
		public int getTotal() {
			return total;
		}
		public void setTotal(int total) {
			this.total = total;
			setText();
		}
		public void reset()
		{
			ready = 0;
			setText();
		}
		public void decrement()
		{
			if(ready > 0)
				ready--;
			setText();
		}	
		public void increment()
		{
			if(ready < total)
				ready++;
			setText();
		}
	}
	private static final long serialVersionUID = 1L;

	public Container contents;


	//top left components
	private JPanel playerPanel;
	private JLabel labelTimeLeft;
	private JLabel labelPlayers;
	private ArrayList<PlayerEntry> playerEntries;

	private ReadyLabel labelReadyPlayers;
	private JRadioButton readyCheckBox;

	//top right components
	private JButton leaveGame;

	//bottom left components
	private JPanel topLeft;
	private JPanel topRight;
	private JPanel bottomLeft;
	private JPanel bottomRight;

	private JConnect3Slot[][] grid;
	private Box[] rows;
	private Box columns;

	//bottom right components
	private javax.swing.JTextArea chatBox;
	private javax.swing.JTextField chatInput;
	private javax.swing.JPanel chatPanel;
	private javax.swing.JButton send;
	private javax.swing.JScrollPane jScrollPane1;

	public GameBoard gb;
	public GameLogic gl;
	private Protocol proto = null;

	public GUI_Game_Board(GameBoard new_gb, GameLogic new_gl, Protocol proto){
		super("Connect 3 - Game Board");

		gb=new_gb;
		gl=new_gl;
		contents = getContentPane();
		topLeft=new JPanel();
		topRight=new JPanel();
		bottomLeft=new JPanel();
		bottomRight=new JPanel();
		this.proto = proto;

//		Add to the top left 
		playerPanel = new JPanel();
		playerPanel.setLayout(new BoxLayout(playerPanel, BoxLayout.Y_AXIS));
		JPanel tl = new JPanel();
		tl.setLayout(new BoxLayout(tl, BoxLayout.Y_AXIS));

		labelTimeLeft = new JLabel("Time Left");
		labelPlayers = new JLabel("                Players");

		labelReadyPlayers = new ReadyLabel();
		readyCheckBox = new JRadioButton();
		readyCheckBox.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent arg0) {
				clickedReady();
				
			}			
		});


		JPanel group1 = new JPanel(new FlowLayout(FlowLayout.LEFT));
		//labelTimeLeft.setAlignmentX(Component.LEFT_ALIGNMENT);
		//labelPlayers.setAlignmentX(Component.LEFT_ALIGNMENT);
		group1.setAlignmentX(Component.LEFT_ALIGNMENT);
		group1.add(labelTimeLeft);
		group1.add(labelPlayers);
		tl.add(group1);
		
		playerEntries=new ArrayList<PlayerEntry>();
		tl.add(playerPanel);
		JPanel group2 = new JPanel(new FlowLayout(FlowLayout.LEFT));
		group2.add(labelReadyPlayers);
		group2.add(readyCheckBox);
		tl.add(group2);

		topLeft.add(tl);

		
		
		//Add to the top right
		leaveGame = new JButton("leave game");


		//Add to the bottom left
		//game grid
		grid= new JConnect3Slot[gb.getXDimension()][gb.getYDimension()];


		rows= new Box[gb.getYDimension()];
		columns = Box.createVerticalBox();
		for(int y=0; y<gb.getYDimension(); y++){
			rows[y] = Box.createHorizontalBox();			
			for(int x=0; x<gb.getXDimension(); x++){
				grid[x][y]=new JConnect3Slot();
				grid[x][y].addActionListener(new java.awt.event.ActionListener() {
					public void actionPerformed(java.awt.event.ActionEvent evt) {
						gridClick(evt);
					}
				}
				);
				rows[y].add(grid[x][y]);
			}				
		}
		for( int y=gb.getYDimension()-1; y>=0; y--){
			columns.add(rows[y]);
		}				

		//Add to the bottom right
		chatPanel = new javax.swing.JPanel();
		chatBox = new javax.swing.JTextArea();
		chatInput = new javax.swing.JTextField();
		send = new javax.swing.JButton();

		chatPanel.setName("chatPanel"); 

		chatBox.setColumns(20);
		chatBox.setRows(5);
		chatBox.setName("chatBox"); 
		chatBox.setEditable(false);
		jScrollPane1 = new javax.swing.JScrollPane();
		jScrollPane1.setName("jScrollPane1");

		chatInput.setText(""); // NOI18N
		chatInput.setName("chatInput"); // NOI18N
		jScrollPane1.setViewportView(chatBox);
		chatInput.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent evt) {
				sendKeyPressed(evt);
			}
		});


		send.setText("send"); // NOI18N
		send.setName("send"); // NOI18N
		send.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent evt) {
				sendKeyPressed(evt);
			}
		});

		javax.swing.GroupLayout chatPanelLayout = new javax.swing.GroupLayout(chatPanel);
		chatPanel.setLayout(chatPanelLayout);
		chatPanelLayout.setHorizontalGroup(
				chatPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
				.addGroup(chatPanelLayout.createSequentialGroup()
						.addContainerGap()
						.addGroup(chatPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
								.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 267, Short.MAX_VALUE)
								.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, chatPanelLayout.createSequentialGroup()
										.addComponent(chatInput, javax.swing.GroupLayout.DEFAULT_SIZE, 204, Short.MAX_VALUE)
										.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
										.addComponent(send)))
										.addContainerGap())
		);
		chatPanelLayout.setVerticalGroup(
				chatPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
				.addGroup(chatPanelLayout.createSequentialGroup()
						.addContainerGap()
						.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 157, javax.swing.GroupLayout.PREFERRED_SIZE)
						.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
						.addGroup(chatPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
								.addComponent(send)
								.addComponent(chatInput, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
								.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
		);


		bottomRight.add(chatPanel);

		contents.setLayout(new GridLayout(2,2));		
		Box bv = Box.createVerticalBox();		

		topRight.add(leaveGame);
		bottomLeft.add(columns);
		contents.add(topLeft);
		contents.add(topRight);
		contents.add(bottomLeft);
		contents.add(bottomRight);




		leaveGame.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				leaveGame(evt);
			}
		}
		);
		
		
		pack();
		setResizable(false);
		
		setVisible(true);
		toFront();
	}

	public class PlayerEntry extends JPanel{
		/**
		 * 
		 */
		private static final long serialVersionUID = 1L;
		private JLabel playerEntry_Time;
		private JTextArea playerEntry_Color;
		private JLabel playerEntry_Player;
		private JLabel playerEntry_Turn;

		public PlayerEntry(){
			super(new FlowLayout(FlowLayout.LEFT));
			playerEntry_Time = new JLabel("00:00");
			playerEntry_Color = new JTextArea(1,1);
			playerEntry_Color.setEditable(false);
			playerEntry_Player = new JLabel("Unitialized");			
			playerEntry_Turn = new JLabel("");
		}

		public void setTime(String time){
			playerEntry_Time.setText(time);
		}

		public void setColor(Color color){
			playerEntry_Color.setBackground(color);
		}

		public void setPlayer(String playerName){
			playerEntry_Player.setText(playerName);
		}

		public String getPlayer(){
			return playerEntry_Player.getText();
		}

		public void giveTurn(){
			playerEntry_Turn.setText("your turn");
			topLeft.revalidate();
		}

		public void removeTurn(){
			playerEntry_Turn.setText("");
			topLeft.revalidate();
		}

		public void addToPanel(JPanel p){
			p.setAlignmentX(Component.LEFT_ALIGNMENT);
			p.setLocation(0, 0);			
			add(playerEntry_Time);
			add(new JLabel("  "));
			add(playerEntry_Color);
			add(new JLabel("  "));			
			add(playerEntry_Player);
			add(playerEntry_Turn);
			p.add(this);
		}

	}

	public PlayerEntry getPlayerFromList(String playerName){
		for(int i =0 ; i<playerEntries.size();i++){
			if(playerName.equals(playerEntries.get(i).getPlayer())){
				return playerEntries.get(i);
			}
		}
		return null;			
	}

	public void addPlayer(String name, Color col)
	{
		PlayerEntry p = new PlayerEntry();
		p.setColor(col);
		p.setPlayer(name);
		p.addToPanel(playerPanel);
		playerPanel.revalidate();
		playerEntries.add(p);
		pack();
	}
	
	public void removePlayer(String playerName){
		for(int i =0 ; i<playerEntries.size();i++){
			if(playerName.equals(playerEntries.get(i).getPlayer())){
				playerPanel.remove(playerEntries.get(i));
				playerEntries.remove(i);
			}
		}
		playerPanel.validate();
		pack();
	}
	
	public void clickedReady(){
		readyCheckBox.setEnabled(false);
		proto.sendReady();
	}

	public boolean isReady(){
		return readyCheckBox.isSelected();
	}

	public void leaveGame(ActionEvent ae){
		proto.sendDisconnect(0);
		dispose();
	}

	public void gridClick(ActionEvent ae){		

		for(int y=0; y<gb.getYDimension(); y++){								
			for(int x=0; x<gb.getXDimension(); x++)
			{
				if(grid[x][y]==((JButton)ae.getSource())){

					GamePiece gp = gl.getTurn().generatePiece();
					gp.x = x;
					gp.y = 0;
					proto.sendMove(gp);
				}

			}
		}
	}

	public void setNumPlayers(int n)
	{
		labelReadyPlayers.setTotal(n);
	}
	
	public void incrementReady()
	{
		labelReadyPlayers.increment();
	}
	
	public void decrementReady()
	{
		labelReadyPlayers.decrement();
	}
	
	public void resetReady()
	{
		labelReadyPlayers.reset();
	}
	
	//#############
	//Chat hooks
	//#############
	private void sendKeyPressed(ActionEvent ae) {
		String input = chatInput.getText();
		if(!input.equals("")){
			proto.sendChat(input);
			chatInput.setText("");
		}

	}

	public void addChatMessage(String chat)
	{
		chatBox.append(chat);
	}

	public void move(GamePiece p)
	{
		if(p.y >= 0)
			grid[p.x][p.y].setBackground(p.getColor());
		
	}
	public void reset()
	{
		readyCheckBox.setSelected(false);
		resetReady();
		readyCheckBox.setEnabled(true);
		
		for(int y=0; y<gb.getYDimension(); y++){								
			for(int x=0; x<gb.getXDimension(); x++)
			{
				grid[x][y].setBackground(Color.LIGHT_GRAY);				
			}
		}
		
		for(Iterator<PlayerEntry> it = playerEntries.iterator(); it.hasNext();)
			it.next().removeTurn();
		if(playerEntries.size() > 0)
			playerEntries.get(0).giveTurn();
	}
}
